package com.baselib.libnetwork.net.request;

import com.baselib.libnetwork.net.model.HttpParams;
import com.baselib.libnetwork.net.utils.HttpUtils;
import com.baselib.libnetwork.net.model.HttpHeaders;

import org.json.JSONObject;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;

import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;

/**
 * @author lixuce
 * @version v1.0
 * @description
 * @since 2017/10/29
 */

public abstract class FileRequest<T, R extends FileRequest> extends CustomRequest<T, R> {

    private static final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");
    protected transient File file;                  //单纯的上传一个文件
    protected transient MediaType mediaType;        //上传的MIME类型
    protected String content;                       //上传的文本内容
    private boolean isNullFile = false;   //判断是否有文件

    public FileRequest(String url) {
        super(url);
    }

    public void setNullFile(boolean isNullFile) {
        this.isNullFile = isNullFile;
    }

    @Override
    protected RequestBody generateRequestBody() {
        if (content != null && mediaType != null) {
            return RequestBody.create(mediaType, content);    //上传字符串数据
        }
        if (file != null && mediaType != null) {
//            MediaType mediaType = MediaType.parse("multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW");
//            RequestBody body = RequestBody.create(mediaType, "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data;" +
//                    " name=\"user_head_pic\"; filename="+file.getAbsolutePath()+"\r\nContent-Type: image/png\r\n\r\n\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--");
//            return body;

            return new MultipartBody.Builder()
                    .setType(MultipartBody.FORM)
                    .addFormDataPart("user_head_pic", file.getName(), RequestBody.create(MultipartBody.FORM, file))
                    .addFormDataPart("Content-Type", "image/png")
                    .build();
        }
        if (isNullFile) {
            //表单提交，但是没有文件文件
            MultipartBody.Builder multipartBodybuilder = new MultipartBody.Builder().setType(MultipartBody.FORM);
            //拼接键值对
            if (!params.urlParamsMap.isEmpty()) {
                for (Map.Entry<String, List<String>> entry : params.urlParamsMap.entrySet()) {
                    List<String> urlValues = entry.getValue();
                    for (String value : urlValues) {
                        multipartBodybuilder.addFormDataPart(entry.getKey(), value);
                    }
                }
            }
            return multipartBodybuilder.build();
        }
        return HttpUtils.generateMultipartRequestBody(params);
    }

    protected okhttp3.Request.Builder generateRequestBuilder(RequestBody requestBody) {
        try {
            headers(HttpHeaders.HEAD_KEY_CONTENT_LENGTH, String.valueOf(requestBody.contentLength()));
            if (file != null) {
                headers(HttpHeaders.HEAD_KEY_CONTENT_TYPE, "multipart/form-data");
            }
        } catch (IOException e) {
        }
        okhttp3.Request.Builder requestBuilder = new okhttp3.Request.Builder();
        return HttpUtils.appendHeaders(requestBuilder, headers);
    }


    @SuppressWarnings("unchecked")
    public R params(String key, File file) {
        params.put(key, file);
        return (R) this;
    }

    /**
     * 注意使用该方法上传字符串会清空实体中其他所有的参数，头信息不清除
     */
    @SuppressWarnings("unchecked")
    public R upFile(File file) {
        this.file = file;
        this.mediaType = HttpUtils.guessMimeType(file.getName());
        return (R) this;
    }

    /**
     * 注意使用该方法上传字符串会清空实体中其他所有的参数，头信息不清除
     */
    @SuppressWarnings("unchecked")
    public R upFile(File file, MediaType mediaType) {
        this.file = file;
        this.mediaType = mediaType;
        return (R) this;
    }


    /**
     * 注意使用该方法上传字符串会清空实体中其他所有的参数，头信息不清除
     */
    @SuppressWarnings("unchecked")
    public R upJson(String json) {
        this.content = json;
        this.mediaType = HttpParams.MEDIA_TYPE_JSON;
        return (R) this;
    }

    /**
     * 注意使用该方法上传字符串会清空实体中其他所有的参数，头信息不清除
     */
    @SuppressWarnings("unchecked")
    public R upJson(JSONObject jsonObject) {
        this.content = jsonObject.toString();
        this.mediaType = HttpParams.MEDIA_TYPE_JSON;
        return (R) this;
    }

}
